import time
import configs
import datetime
import difflib


def check_internet():
    import requests

    try:
        # requests.get("http://google.com")
        requests.get("https://yandex.ru")  # Хули Импортозамещение
        return True
    except requests.ConnectionError:
        return False


def write_file(vosk_str: str, name: str) -> None:
    # запись в файл информации о выполненных функциях
    check_record = open(name, "a")
    check_record.write(vosk_str)
    check_record.close()


def write_meta_data(func: str, file_name: str, tags: list = []) -> None:
    # Сбор о информации о выполненых командах и времени их исполнении
    if configs.meta_data:
        if len(tags) != 0:
            str_tags = "".join(tags)
        else:
            str_tags = ""
        now = datetime.datetime.now()
        date_call_func = datetime.datetime(
            now.year, now.month, now.day, now.hour, now.minute
        )
        write_file(
            f"{func} {str_tags} {date_call_func}\n", f"{configs.path_bd}{file_name}"
        )


def util_find(str_source: str, str_find: str) -> bool:
    if str_source.find(str_find) != -1:
        return True
    else:
        return False


def restart_modul():
    # !!!
    # obj_configs.obj_import_egg.settings()
    return "Модули переподключены"


def json_renewal() -> str:
    # Дописать !!!
    # configs.cmds = setting_get_set.read_config("configs.json")
    # configs.settings = setting_get_set.read_config("settings.json")
    # configs.language = setting_get_set.read_config("language.json")
    return "Конфигурация ядра обновлена"


def dec_queue_clear() -> None:
    if configs.stream_speech.qsize() >= 10:
        configs.stream_speech.queue.clear()


def find_entry_all(a_str: str, sub: str):
    start = 0
    list_index = []
    list_len = []
    while True:
        start = a_str.find(sub, start)
        if start != -1:
            list_index.append(start)
            start = start + len(sub)
            list_len.append(start)
        if start == -1:
            break
    return list_index, list_len


def search_parmas(func: str, sub: str) -> list:
    tags = []
    start = 0
    old = 0
    param = "params_"
    index_tags = func.find(param)
    params = func[index_tags + len(param) : len(func)]
    while True:
        start = params.find(sub, start)
        if start != -1:
            start = start + len(sub)
            tags.append(params[old : start - 1])
            old = start
        if start == -1:
            break
    return tags


def search_entry_all(func: str, sub: str) -> list:
    tags = []
    start = 0
    old = 0
    params = func[0 : len(func)]
    while True:
        start = params.find(sub, start)
        if start != -1:
            start = start + len(sub)
            tags.append(params[old : start - 1])
            old = start
        if start == -1:
            break
    return tags


def queue_voice_str_api():
    """
    Описание:

    Функция для чтения очереди Queue потока распознования речи.
    Также в функции присуствует логирование.
    Функция ожидает пока речь не будет распознана.

    Возращает:

    **Строку распознаной речи**

    """

    if len(configs.buff_mess_speech["mess"]) >= configs.buff_mess_speech_count:
        configs.buff_mess_speech = {"mess": [], "data": []}
    voice_str = configs.stream_speech.get()
    configs.speech_recognition_str_api = voice_str
    configs.buff_mess_speech["mess"].append(voice_str)
    configs.buff_mess_speech["data"].append(time.time())
    return voice_str


def queue_voice_time_str_api(say_expectatio=configs.say_expectatio):
    """
    Описание:

    Функция для чтения очереди Queue потока распознования речи,
    в цикле течение **say_expectatio** заданной в конфигурации.
    Также в функции присуствует логирование.

    Параметры функции:

    `say_expectatio`: Параметра ожидания фразы в секундах

    Возращает:

    **Строку распознаной речи или пустую строку**

    """
    if len(configs.buff_mess_speech["mess"]) >= configs.buff_mess_speech_count:
        configs.buff_mess_speech = {"mess": [], "data": []}
    start_time = time.time()
    # configs.queue_message_external_events.empty() == False
    cheek_message = False
    while not cheek_message:
        cheek_message = configs.stream_speech.empty()
        if not cheek_message:
            # configs.queue_message_external_events.get()
            voice_str = configs.stream_speech.get()
            configs.speech_recognition_str_api = voice_str
            configs.buff_mess_speech["mess"].append(voice_str)
            configs.buff_mess_speech["data"].append(time.time())
            return voice_str

        else:
            if (time.time() - start_time) >= say_expectatio:
                cheek_message = True
                # break
                return ""
    return ""


def queue_voice_time_str_api_name(obj_work_mode, say_expectatio=configs.say_expectatio):
    """
    Описание:

    Функция для чтения очереди Queue потока распознования речи,
    в цикле течение **say_expectatio** заданной в конфигурации.
    Также в функции присуствует логирование.

    Параметры функции:

    `say_expectatio`: Параметра ожидания фразы в секундах

    Возращает:

    **Строку распознаной речи или пустую строку**

    """
    if len(configs.buff_mess_speech["mess"]) >= configs.buff_mess_speech_count:
        configs.buff_mess_speech = {"mess": [], "data": []}
    start_time = time.time()
    # configs.queue_message_external_events.empty() == False
    cheek_message = False
    while not cheek_message:
        # print(1)
        cheek_message = configs.stream_speech.empty()
        # print(cheek_message,2)
        obj_work_mode.event_loop()
        # print(22222)
        if not cheek_message:
            # configs.queue_message_external_events.get()
            voice_str = configs.stream_speech.get()
            configs.speech_recognition_str_api = voice_str
            configs.buff_mess_speech["mess"].append(voice_str)
            configs.buff_mess_speech["data"].append(time.time())
            return voice_str

        else:
            # print(cheek_message, 2222)
            if (time.time() - start_time) >= say_expectatio:
                cheek_message = True
                # break
                return ""
    return ""


class Cheek_Queue:
    def __init__(self, stop="", stop_flag=True):
        self.stop = stop
        self.stop_flag = stop_flag

    def set_Queue(self, stop_sr) -> None:
        self.stop_sr = stop_sr

    def cheek_Queue(self):
        if not self.stop_sr.empty():
            self.stop = self.stop_sr.get()
        elif self.stop_sr.empty():
            pass
        if self.stop == "True" and not self.stop_flag:
            stop_flag = True
            return None
        if self.stop == "True" and self.stop_flag:
            return self.stop_flag
        elif self.stop == "False":
            stop_flag = False
            return stop_flag

    def iterator(self, iter_now, len_data, iter_step):
        if len_data == iter_step:
            iter_now = 0
            # iter_now=0
        elif iter_now >= len_data:
            if iter_step > 0:
                iter_now = len_data - iter_step
            elif iter_step < 0:
                iter_now = len_data + iter_step
            if iter_now < 0:
                iter_now = 0
                iter_step = len_data
        elif (iter_now + iter_step) >= len_data and iter_step > 0:
            if len_data >= iter_now:
                temp = len_data - iter_now
                if temp != 0 and iter_step > temp:
                    iter_step = temp
                    print(temp)
                    # iter_now+=iter_step

        elif iter_now <= 0:
            iter_now = 0
        elif (iter_now + iter_step) < 0 and iter_step < 0:
            iter_now = 0
        else:
            pass
        if len_data < abs(iter_step):
            iter_step = len_data
        return iter_now, abs(iter_step)


def fuzz_word_cheek(len_words):
    if configs.flexible_probability_cmd_cmds:
        par = 100 / len_words
        sum_par = par * configs.count_error_word
        if int(sum_par) < 100:
            if (100 - sum_par) >= configs.PROBABILITY_CMD_CONST:
                configs.probability_cmd = 100 - sum_par
            else:
                configs.probability_cmd = configs.PROBABILITY_CMD_CONST
    else:
        configs.probability_cmd = configs.PROBABILITY_CMD_CONST


def error_correction(input_str: str, dict_words, name_err: int = 1, cof_wer=0.7) -> str:
    input_list = input_str.split(" ")
    list_str = []
    for str_i in input_list:
        exact_words = difflib.get_close_matches(str_i, dict_words, name_err, cof_wer)
        if len(exact_words) > 0:
            list_str.append(exact_words[0])
        else:
            list_str.append(str_i)

    return " ".join(list_str)


def iterator(iter_now, len_data, iter_step):
    if len_data == iter_step:
        iter_now = 0
        # iter_now=0
    elif iter_now >= len_data:
        if iter_step > 0:
            iter_now = len_data - iter_step
        elif iter_step < 0:
            iter_now = len_data + iter_step
        if iter_now < 0:
            iter_now = 0
            iter_step = len_data
    elif (iter_now + iter_step) >= len_data and iter_step > 0:
        if len_data >= iter_now:
            temp = len_data - iter_now
            if temp != 0 and iter_step > temp:
                iter_step = temp
                print(temp)
                # iter_now+=iter_step

    elif iter_now <= 0:
        iter_now = 0
    elif (iter_now + iter_step) < 0 and iter_step < 0:
        iter_now = 0
    else:
        pass
    if len_data < abs(iter_step):
        iter_step = len_data
    return iter_now, abs(iter_step)


def del_func_str(func_name, str_mess):
    list_str_cmd = configs.cmds_void[func_name]["word_list"]
    error_correction(str_mess, list_str_cmd)
    for str_cmd in list_str_cmd:
        if str_cmd in str_mess:
            data_key = str_mess.replace(str_cmd, "")
            return data_key[1 : len(data_key)]
        else:
            # Исправить
            return None


class Error_log:
    def __init__(self) -> None:
        pass

    def set_error(error):
        print(error)
